home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXT Education Software Sampler 1992 Fall
/
NeXT Education Software Sampler 1992 Fall.iso
/
SoundAndMusic
/
cmix
/
Minc
/
p.y
< prev
next >
Wrap
Text File
|
1991-03-16
|
5KB
|
215 lines
%{
#include "defs.h"
#include "lex.yy.c"
#include "ext.h"
#define YYDEBUG
#define MAXIDLIST 200
int i1,i2,i3,i4,i5,i6,i7,i8,i9;
double atof(),f1,f2,f3,f4,f5,f6,f7,f8,f9,d1;
char *c1,*c2,*c3;
Tree tp1,tp2,tp3,tp4,tp5,tp6,tp7,tp8,tp9;
SYMBOL *sp1,*sp2,*sp3,*sp4,*sp5,*sp6,*sp7,*sp8,*sp9;
int idcount =0;
char *idlist[MAXIDLIST];
int interactive;
char str[200];
char strp;
int flerror; /* set if there was an error during parsing */
int level=0; /* keeps track whether we are in a structure*/
%}
%left <ival>LOWPRIO
%left <ival> '='
%left <ival>T_OR
%left <ival>T_AND
%left <ival> T_EQU UNEQU
%left <ival>'<' '>' LESSEQU GTREQU
%left <ival>'+' '-'
%left <ival>'*' '/'
%left <ival>T_POW
%left <ival> CASTTOKEN
%token <ival>FLT CTOO CTOL OTOL OTOC LTOO LTOC
%token <ival>ID NUM T_NOT IF ELSE FOR WHILE
%token <ival>T_TRUE T_FALSE STRING
%type <trees> stml stmt rstmt bexp expl exp str
%type <str> id
%%
prg: stml {program = $1;return (0);}
;
stml : stmt {$$ = $1;}
| stml stmt {$$ = tseq($1,$2);}
| stmt ";" {$$ = $1;}
| stml stmt ";" {$$ = tseq($1,$2);}
;
stmt: FLT idl { declare(T_FLOAT);idcount=0;}
| rstmt {
if (level==0)
$$ = go($1);
else $$ = $1;
}
| IF level bexp stmt {
level--;
$$ = go(tif($3,$4));
}
| IF level bexp stmt ELSE stmt {
level--;
$$ = go(tifelse($3,$4,$6));
}
| WHILE level bexp stmt {
level--;
$$ = go(twhile($3,$4));
}
| FOR level '(' stmt ';' bexp ';' stmt ')' stmt {
level--;
$$ = go(tfor($4,$6,$8,$10));
}
| '{' stml '}' {$$ = $2;}
| error FLT {flerror = 1;$$=tnoop();}
| error IF {flerror = 1;$$=tnoop();}
| error WHILE {flerror = 1;$$=tnoop();}
| error FOR {flerror = 1;$$=tnoop();}
| error '{' {flerror = 1;$$=tnoop();}
| error ELSE {flerror = 1;$$=tnoop();}
| error ';' {flerror = 1;$$=tnoop();}
;
/* statements that can return a value */
level: {
level++;
}
rstmt: id '=' exp {
sp1=lookup($1);
if (sp1==NULL) {
sprintf(str,"note: %s has been auto declared",$1);
sp1=install($1,S_GLOBAL,T_FLOAT);
yyerror (str);
}
$$ = tstore(tname(sp1),$3);
}
| id '(' expl ')' {$$ = tcall ($3,$1);}
;
idl: id { idlist[idcount++]=$1;}
| idl ',' id { idlist[idcount++]=$3;}
;
id: ID { $$ = strsave(yytext);}
;
expl: exp {$$ = targ(tnoargs(),$1);}
| expl ',' exp { $$ = targ($1,$3); }
/* NOTE: on casting of strings: first, cast char* into an int, then
cast the int into a double(not float). To convert back, do just the
opposite */
| str {
$$ = targ(tnoargs(),$1);
}
| expl ',' str {
$$ = targ($1,$3);
}
| {$$ = tnoargs();}
;
str: STRING {
c1 = yytext + 1;
c1[strlen(c1)-1]= '\0';
/* Here we do some weird conversion from char* to int to double.
* It is a hack that allows to pass strings to cmix functions,
* in a way, that only the function needs to know about it.
* It very likely to be machine dependent, so you might have to hack it
* if it doesn't work on your system. If you do, send me mail. ***lars.
* (It might help to look at the assembler output produced by cc)
*/
i1 = strsave(c1);
d1 = (double) i1;
$$ = tconstf(d1);
}
;
bexp: exp %prec LOWPRIO { $$ = $1;}
| T_NOT bexp %prec UNEQU { $$ = tnot($2); }
| bexp T_AND bexp { $$ = tcand($1,$3); }
| bexp T_OR bexp { $$ = tcor($1,$3); }
/* note the comparison of booleans */
| bexp T_EQU bexp { $$ = trel(EQ,$1,$3); }
| exp '<' exp { $$ = trel(LT,$1,$3); }
| exp '>' exp { $$ = trel(GT,$1,$3);}
| exp UNEQU exp { $$ = trel(NEQ,$1,$3);}
| exp LESSEQU exp { $$ = trel(LEQ,$1,$3); }
| exp GTREQU exp { $$ = trel(GEQ,$1,$3); }
| T_TRUE {
$$ = trel (EQ,tconstf(1.0),tconstf(1.0));
}
| T_FALSE {
$$ = trel (NEQ,tconstf(1.0),tconstf(1.0));
}
;
exp: exp T_POW exp { $$ = top(POW,$1,$3); }
| rstmt { $$ = $1;}
| exp '*' exp { $$ = top(MUL,$1,$3); }
| exp '/' exp { $$ = top(DIV,$1,$3); }
| exp '+' exp { $$ = top(PLUS,$1,$3); }
| exp '-' exp { $$ = top(MINUS,$1,$3); }
| '(' bexp ')' { $$ = $2;}
| NUM {
f1 = atof(yytext);
$$ = tconstf(f1);
}
| '-' NUM %prec CASTTOKEN {
f1 = atof(yytext);
$$ = tconstf(-f1);
}
| id {
sp1=lookup($1);
if (sp1==NULL) {
sprintf(str,"error: %s is not declared",$1);
yyerror (str);
$$ = tconstf(0.0);
}else $$ = tname(sp1);
}
;
%%
declare(type)
int type;
{
int i1;
SYMBOL *sp1;
for (i1=0;i1<idcount;i1++) {
sp1 = lookup (idlist[i1]);
if (sp1 != NULL) {
sprintf(str,"warning: variable redefined: %s",idlist[i1]);
/* note this handling may be illegal in arbitrary scoping */
sp1->type = type;
yyerror(str);
}
else install(idlist[i1],S_GLOBAL,type);
}
}
Tree go (t1)
Tree t1;
{
if (interactive && level==0) exct(t1);
if (interactive && level==0) free_tree(t1);
return (t1);
}